#include "../source/server.hpp"
using namespace std;

void allEventHandle(channel* ch, eventLoop* loop)
{
    int fd = ch->fd();
    lg(Info, "fd:%d get event", fd);
    loop->delayTimer(ch->fd());

}

void readHandle(channel* ch, eventLoop* loop)
{
    int fd = ch->fd();
    lg(Info, "fd:%d get read event", fd);
    char inBuffer[1024];
    ssize_t n = read(fd, inBuffer, sizeof inBuffer - 1);
    if (n > 0)
    {
        inBuffer[n] = 0;
        lg(Info, "fd: %d $ %s", fd, inBuffer);
        // 读取成功，可以进行写事件操作了
        ch->setMonitorWrite();
    }
    else
    {
        lg(Info, "fd: %d close", fd);
        // epl->epollFileDel(ch);
        // 如果对端已经关闭了连接，那么loop模块中不仅仅要关闭对ch的监控，还要关闭time时间
        loop->delFdMonitor(ch);
        loop->cancelTimer(fd);
        // 在 channel 的析构函数中会close掉fd
        delete ch;
    }
    // epl->epollUpdate(ch, ch->getEvent());
}

void writeHandle(channel* ch)
{
    // 在向一个已经关闭的连接写入数据时，会触发SIGPIPE信号，导致进程推出
    // 所以连接管理应该在读事件处理内部进行
    int fd = ch->fd();
    lg(Info, "fd:%d get write event", fd);
    string s = "今天天气真好!";
    ssize_t n = write(fd, s.c_str(), s.size());
    ch->delMonitorWrite();
    if (n <= 0)
    {
        return;
    }
}

void closeHandle(channel* ch)
{
    int fd = ch->fd();
    lg(Info, "fd:%d get close event", fd);
}

void errorHandle(channel* ch)
{
    int fd = ch->fd();
    lg(Info, "fd:%d get close event", fd);
}

void overTimeHandler(channel* ch)
{
    lg(Info, "this channel, fd: %d overtime, delete the channel", ch->fd());
    ch->revChannel();
    delete ch;
}

void onaccept(tcpSocket& svr, eventLoop* loop)
{
    int newfd = svr.accept();
    if (newfd < 0)
    {
        lg(Warning, "tcp socket accept error!, errno:%d , \"%s\"", errno, strerror(errno));
        return;
    }
    lg(Info, "socket get a new link, fd:%d", newfd);
    // 为新连接创建channel
    channel* newch = new channel(loop, newfd);
    // 为该channel设置各种回调函数
    newch->setAllCb([=]()
        { allEventHandle(newch, loop); });
    newch->setReadCb([=]()
        { readHandle(newch, loop); });
    newch->setWriteCb([=]()
        { writeHandle(newch); });
    newch->setErrCb([=]()
        { errorHandle(newch); });
    newch->setCloseCb([=]()
        { closeHandle(newch); });
    // 设置channel监控写事件
    newch->setMonitorRead();
    loop->addTimer(newch->fd(), 5, [=] { overTimeHandler(newch); });
}



int main()
{
    tcpSocket svr;
    if (!svr.createServer(8080, false))
        return 1;
    eventLoop loop;
    channel* listenSock = new channel(&loop, svr.fd());
    listenSock->setReadCb([&]
        { acceptor(svr, &loop); }); // 为listen套接字绑定可读事件监控
    listenSock->setMonitorRead();
    loop.init();
    loop.start();

    // while (true)
    // {
    //     int fd = svr.accept();
    //     tcpSocket client(fd);
    //     std::string s;
    //     while (client.read(&s, 1024, false) != 0)
    //     {
    //         string ret = string("tcp echo@ ") + s;
    //         client.send(ret, false);
    //     }
    // }
}